package main

import (
	"encoding/json"
	"flag"
	"io/ioutil"
	"net/http"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/log"
)

//常量
const (
	namespace = "namenode"
)

//变量
var (
	listenAddress  = flag.String("web.listen-address", ":9070", "Address on which to expose metrics and web interface.")
	metricsPath    = flag.String("web.telemetry-path", "/metrics", "Path under which to expose metrics.")
	namenodeJmxUrl = flag.String("namenode.jmx.url", "http://192.168.10.10:50070/jmx", "Hadoop JMX URL.")
)

//数据结构
type Exporter struct {
	url                      string
	MissingBlocks            prometheus.Gauge
	CapacityTotal            prometheus.Gauge
	CapacityUsed             prometheus.Gauge
	CapacityRemaining        prometheus.Gauge
	CapacityUsedNonDFS       prometheus.Gauge
	BlocksTotal              prometheus.Gauge
	FilesTotal               prometheus.Gauge
	CorruptBlocks            prometheus.Gauge
	ExcessBlocks             prometheus.Gauge
	StaleDataNodes           prometheus.Gauge
	pnGcCount                prometheus.Gauge
	pnGcTime                 prometheus.Gauge
	cmsGcCount               prometheus.Gauge
	cmsGcTime                prometheus.Gauge
	heapMemoryUsageCommitted prometheus.Gauge
	heapMemoryUsageInit      prometheus.Gauge
	heapMemoryUsageMax       prometheus.Gauge
	heapMemoryUsageUsed      prometheus.Gauge
	isActive                 prometheus.Gauge
	//RpcActivityForPort8020 数据流量
	ReceivedBytes            prometheus.Gauge
	SentBytes                prometheus.Gauge
	RpcQueueTimeNumOps       prometheus.Gauge
	//请求处理延迟
	RpcQueueTimeAvgTime      prometheus.Gauge
	RpcProcessingTimeNumOps  prometheus.Gauge
	RpcProcessingTimeAvgTime prometheus.Gauge
	//验证和授权
	RpcAuthenticationFailures   prometheus.Gauge
	RpcAuthenticationSuccesses  prometheus.Gauge
	RpcAuthorizationFailures    prometheus.Gauge
	RpcAuthorizationSuccesses   prometheus.Gauge
	//当前连接数
	NumOpenConnections          prometheus.Gauge
	//RPC处理队列长度
	CallQueueLength             prometheus.Gauge
	//
	PendingDataNodeMessageCount prometheus.Gauge
	TransactionsSinceLastCheckpoint prometheus.Gauge
	LastCheckpointTime              prometheus.Gauge
	MemNonHeapUsedM                 prometheus.Gauge
	MemNonHeapCommittedM            prometheus.Gauge
	MemHeapUsedM                    prometheus.Gauge
	MemHeapCommittedM               prometheus.Gauge
	MemHeapMaxM                     prometheus.Gauge
	MemMaxM                         prometheus.Gauge
	GcCount                         prometheus.Gauge
	GcTimeMillis                    prometheus.Gauge
	ThreadsNew                      prometheus.Gauge
	ThreadsRunnable                 prometheus.Gauge
	ThreadsBlocked                  prometheus.Gauge
	ThreadsWaiting                  prometheus.Gauge
	ThreadsTerminated               prometheus.Gauge
	LogFatal                   prometheus.Gauge
	LogError                   prometheus.Gauge
	LogWarn                    prometheus.Gauge
	LogInfo                    prometheus.Gauge
	NumStaleStorages           prometheus.Gauge
	NumberOfMissingBlocks      prometheus.Gauge
	Total                      prometheus.Gauge
	Used                       prometheus.Gauge
	Free                       prometheus.Gauge
	PercentUsed                prometheus.Gauge
	BlockPoolUsedSpace         prometheus.Gauge
	PercentBlockPoolUsed       prometheus.Gauge
	PercentRemaining           prometheus.Gauge
	TotalBlocks                prometheus.Gauge
	TotalFiles                 prometheus.Gauge
	AllowSnapshotOps           prometheus.Gauge
	DisallowSnapshotOps        prometheus.Gauge
	CreateSnapshotOps          prometheus.Gauge
	DeleteSnapshotOps          prometheus.Gauge
	ListSnapshottableDirOps    prometheus.Gauge
	SnapshotDiffReportOps      prometheus.Gauge
	RenameSnapshotOps          prometheus.Gauge
	CreateFileOps              prometheus.Gauge
	GetListingOps              prometheus.Gauge
	DeleteFileOps              prometheus.Gauge
	FileInfoOps                prometheus.Gauge
	GetAdditionalDatanodeOps   prometheus.Gauge
	CreateSymlinkOps           prometheus.Gauge
	GetLinkTargetOps           prometheus.Gauge
	FilesInGetListingOps       prometheus.Gauge
	FilesDeleted               prometheus.Gauge
	FilesCreated               prometheus.Gauge
	FilesAppended              prometheus.Gauge
	TransactionsNumOps         prometheus.Gauge
	TransactionsBatchedInSync  prometheus.Gauge
	GetEditNumOps              prometheus.Gauge
	GetImageNumOps             prometheus.Gauge
	PutImageNumOps             prometheus.Gauge
	SyncsNumOps                prometheus.Gauge
	BlockReceivedAndDeletedOps prometheus.Gauge
	//BlockOpsQueued             prometheus.Gauge
	CacheReportNumOps          prometheus.Gauge
	BlockReportNumOps          prometheus.Gauge
	SyncsAvgTime               prometheus.Gauge
	CacheReportAvgTime         prometheus.Gauge
	GetEditAvgTime             prometheus.Gauge
	GetImageAvgTime            prometheus.Gauge
	PutImageAvgTime            prometheus.Gauge
	TransactionsAvgTime        prometheus.Gauge
	PeakThreadCount            prometheus.Gauge
	ThreadCount                prometheus.Gauge
	DaemonThreadCount          prometheus.Gauge

}

func NewExporter(url string) *Exporter {
	return &Exporter{
		url: url,
		MissingBlocks: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "MissingBlocks",
			Help:      "MissingBlocks",
		}),
		CapacityTotal: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "CapacityTotal",
			Help:      "CapacityTotal",
		}),
		CapacityUsed: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "CapacityUsed",
			Help:      "CapacityUsed",
		}),
		CapacityRemaining: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "CapacityRemaining",
			Help:      "CapacityRemaining",
		}),
		CapacityUsedNonDFS: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "CapacityUsedNonDFS",
			Help:      "CapacityUsedNonDFS",
		}),
		BlocksTotal: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "BlocksTotal",
			Help:      "BlocksTotal",
		}),
		FilesTotal: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "FilesTotal",
			Help:      "FilesTotal",
		}),
		CorruptBlocks: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "CorruptBlocks",
			Help:      "CorruptBlocks",
		}),
		ExcessBlocks: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "ExcessBlocks",
			Help:      "ExcessBlocks",
		}),
		StaleDataNodes: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "StaleDataNodes",
			Help:      "StaleDataNodes",
		}),
		pnGcCount: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "ParNew_CollectionCount",
			Help:      "ParNew GC Count",
		}),
		pnGcTime: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "ParNew_CollectionTime",
			Help:      "ParNew GC Time",
		}),
		cmsGcCount: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "ConcurrentMarkSweep_CollectionCount",
			Help:      "ConcurrentMarkSweep GC Count",
		}),
		cmsGcTime: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "ConcurrentMarkSweep_CollectionTime",
			Help:      "ConcurrentMarkSweep GC Time",
		}),
		heapMemoryUsageCommitted: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "heapMemoryUsageCommitted",
			Help:      "heapMemoryUsageCommitted",
		}),
		heapMemoryUsageInit: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "heapMemoryUsageInit",
			Help:      "heapMemoryUsageInit",
		}),
		heapMemoryUsageMax: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "heapMemoryUsageMax",
			Help:      "heapMemoryUsageMax",
		}),
		heapMemoryUsageUsed: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "heapMemoryUsageUsed",
			Help:      "heapMemoryUsageUsed",
		}),
		isActive: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "isActive",
			Help:      "isActive",
		}),
		ReceivedBytes: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "ReceivedBytes",
			Help:      "ReceivedBytes",
		}),
		SentBytes: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "SentBytes",
			Help:      "SentBytes",
		}),
		RpcQueueTimeNumOps: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "RpcQueueTimeNumOps",
			Help:      "RpcQueueTimeNumOps",
		}),
		RpcQueueTimeAvgTime: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "RpcQueueTimeAvgTime",
			Help:      "RpcQueueTimeAvgTime",
		}),
		RpcProcessingTimeNumOps: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "RpcProcessingTimeNumOps",
			Help:      "RpcProcessingTimeNumOps",
		}),
		RpcProcessingTimeAvgTime: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "RpcProcessingTimeAvgTime",
			Help:      "RpcProcessingTimeAvgTime",
		}),
		RpcAuthenticationFailures: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "RpcAuthenticationFailures",
			Help:      "RpcAuthenticationFailures",
		}),
		RpcAuthenticationSuccesses: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "RpcAuthenticationSuccesses",
			Help:      "RpcAuthenticationSuccesses",
		}),
		RpcAuthorizationFailures: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "RpcAuthorizationFailures",
			Help:      "RpcAuthorizationFailures",
		}),
		RpcAuthorizationSuccesses: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "RpcAuthorizationSuccesses",
			Help:      "RpcAuthorizationSuccesses",
		}),
		NumOpenConnections: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "NumOpenConnections",
			Help:      "NumOpenConnections",
		}),
		CallQueueLength: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:      "CallQueueLength",
			Help:      "CallQueueLength",
		}),
		PendingDataNodeMessageCount: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "PendingDataNodeMessageCount",
			Help: "PendingDataNodeMessageCount",
		}),
		TransactionsSinceLastCheckpoint: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "TransactionsSinceLastCheckpoint",
			Help: "TransactionsSinceLastCheckpoint",
		}),
		LastCheckpointTime: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "LastCheckpointTime",
			Help: "LastCheckpointTime",
		}),
		MemNonHeapUsedM: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "MemNonHeapUsedM",
			Help: "MemNonHeapUsedM",
		}),
		MemNonHeapCommittedM: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "MemNonHeapCommittedM",
			Help: "MemNonHeapCommittedM",
		}),
		MemHeapUsedM: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "MemHeapUsedM",
			Help: "MemHeapUsedM",
		}),
		MemHeapCommittedM: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "MemHeapCommittedM",
			Help: "MemHeapCommittedM",
		}),
		MemHeapMaxM: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "MemHeapMaxM",
			Help: "MemHeapMaxM",
		}),
		MemMaxM: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "MemMaxM",
			Help: "MemMaxM",
		}),
		GcCount: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "GcCount",
			Help: "GcCount",
		}),
		GcTimeMillis: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "GcTimeMillis",
			Help: "GcTimeMillis",
		}),
		ThreadsNew: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "ThreadsNew",
			Help: "ThreadsNew",
		}),
		ThreadsRunnable: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "ThreadsRunnable",
			Help: "ThreadsRunnable",
		}),
		ThreadsBlocked: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "ThreadsBlocked",
			Help: "ThreadsBlocked",
		}),
		ThreadsWaiting: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "ThreadsWaiting",
			Help: "ThreadsWaiting",
		}),
		ThreadsTerminated: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "ThreadsTerminated",
			Help: "ThreadsTerminated",
		}),
		LogFatal: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "LogFatal",
			Help: "LogFatal",
		}),
		LogError: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "LogError",
			Help: "LogError",
		}),
		LogWarn: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "LogWarn",
			Help: "LogWarn",
		}),
		LogInfo: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "LogInfo",
			Help: "LogInfo",
		}),
		NumStaleStorages: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "NumStaleStorages",
			Help: "NumStaleStorages",
		}),
		NumberOfMissingBlocks: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "NumberOfMissingBlocks",
			Help: "NumberOfMissingBlocks",
		}),
		Total: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "Total",
			Help: "Total",
		}),
		Used: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "Used",
			Help: "Used",
		}),
		Free: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "Free",
			Help: "Free",
		}),
		PercentUsed: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "PercentUsed",
			Help: "PercentUsed",
		}),
		BlockPoolUsedSpace: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "BlockPoolUsedSpace",
			Help: "BlockPoolUsedSpace",
		}),
		PercentBlockPoolUsed: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "PercentBlockPoolUsed",
			Help: "PercentBlockPoolUsed",
		}),
		PercentRemaining: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "PercentRemaining",
			Help: "PercentRemaining",
		}),
		TotalBlocks: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "TotalBlocks",
			Help: "TotalBlocks",
		}),
		TotalFiles: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "TotalFiles",
			Help: "TotalFiles",
		}),
		AllowSnapshotOps: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "AllowSnapshotOps",
			Help: "AllowSnapshotOps",
		}),
		DisallowSnapshotOps: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "DisallowSnapshotOps",
			Help: "DisallowSnapshotOps",
		}),
		CreateSnapshotOps: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "CreateSnapshotOps",
			Help: "CreateSnapshotOps",
		}),
		DeleteSnapshotOps: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "DeleteSnapshotOps",
			Help: "DeleteSnapshotOps",
		}),
		ListSnapshottableDirOps: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "ListSnapshottableDirOps",
			Help: "ListSnapshottableDirOps",
		}),
		SnapshotDiffReportOps: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "SnapshotDiffReportOps",
			Help: "SnapshotDiffReportOps",
		}),
		RenameSnapshotOps: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "RenameSnapshotOps",
			Help: "RenameSnapshotOps",
		}),
		CreateFileOps: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "CreateFileOps",
			Help: "CreateFileOps",
		}),
		GetListingOps: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "GetListingOps",
			Help: "GetListingOps",
		}),
		DeleteFileOps: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "DeleteFileOps",
			Help: "DeleteFileOps",
		}),
		FileInfoOps: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "FileInfoOps",
			Help: "FileInfoOps",
		}),
		GetAdditionalDatanodeOps: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "GetAdditionalDatanodeOps",
			Help: "GetAdditionalDatanodeOps",
		}),
		CreateSymlinkOps: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "CreateSymlinkOps",
			Help: "CreateSymlinkOps",
		}),
		GetLinkTargetOps: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "GetLinkTargetOps",
			Help: "GetLinkTargetOps",
		}),
		FilesInGetListingOps: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "FilesInGetListingOps",
			Help: "FilesInGetListingOps",
		}),
		FilesDeleted: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "FilesDeleted",
			Help: "FilesDeleted",
		}),
		FilesCreated: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "FilesCreated",
			Help: "FilesCreated",
		}),
		FilesAppended: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "FilesAppended",
			Help: "FilesAppended",
		}),
		TransactionsNumOps: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "TransactionsNumOps",
			Help: "TransactionsNumOps",
		}),
		TransactionsBatchedInSync: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "TransactionsBatchedInSync",
			Help: "TransactionsBatchedInSync",
		}),
		GetEditNumOps: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "GetEditNumOps",
			Help: "GetEditNumOps",
		}),
		GetImageNumOps: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "GetImageNumOps",
			Help: "GetImageNumOps",
		}),
		PutImageNumOps: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "PutImageNumOps",
			Help: "PutImageNumOps",
		}),
		SyncsNumOps: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "SyncsNumOps",
			Help: "SyncsNumOps",
		}),
		BlockReceivedAndDeletedOps: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "BlockReceivedAndDeletedOps",
			Help: "BlockReceivedAndDeletedOps",
		}),
		//BlockOpsQueued: prometheus.NewGauge(prometheus.GaugeOpts{
		//	Namespace: namespace,
		//	Name:  "BlockOpsQueued",
		//	Help: "BlockOpsQueued",
		//}),
		CacheReportNumOps: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "CacheReportNumOps",
			Help: "CacheReportNumOps",
		}),
		BlockReportNumOps: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "BlockReportNumOps",
			Help: "BlockReportNumOps",
		}),
		SyncsAvgTime: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "SyncsAvgTime",
			Help: "SyncsAvgTime",
		}),
		CacheReportAvgTime: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "CacheReportAvgTime",
			Help: "CacheReportAvgTime",
		}),
		GetEditAvgTime: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "GetEditAvgTime",
			Help: "GetEditAvgTime",
		}),
		GetImageAvgTime: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "GetImageAvgTime",
			Help: "GetImageAvgTime",
		}),
		PutImageAvgTime: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "PutImageAvgTime",
			Help: "PutImageAvgTime",
		}),
		TransactionsAvgTime: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "TransactionsAvgTime",
			Help: "TransactionsAvgTime",
		}),
		PeakThreadCount: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "PeakThreadCount",
			Help: "PeakThreadCount",
		}),
		ThreadCount: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "ThreadCount",
			Help: "ThreadCount",
		}),
		DaemonThreadCount: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: namespace,
			Name:  "DaemonThreadCount",
			Help: "DaemonThreadCount",
		}),

	}
}

// Describe implements the prometheus.Collector interface.
func (e *Exporter) Describe(ch chan<- *prometheus.Desc) {
	e.MissingBlocks.Describe(ch)
	e.CapacityTotal.Describe(ch)
	e.CapacityUsed.Describe(ch)
	e.CapacityRemaining.Describe(ch)
	e.CapacityUsedNonDFS.Describe(ch)
	e.BlocksTotal.Describe(ch)
	e.FilesTotal.Describe(ch)
	e.CorruptBlocks.Describe(ch)
	e.ExcessBlocks.Describe(ch)
	e.StaleDataNodes.Describe(ch)
	e.pnGcCount.Describe(ch)
	e.pnGcTime.Describe(ch)
	e.cmsGcCount.Describe(ch)
	e.cmsGcTime.Describe(ch)
	e.heapMemoryUsageCommitted.Describe(ch)
	e.heapMemoryUsageInit.Describe(ch)
	e.heapMemoryUsageMax.Describe(ch)
	e.heapMemoryUsageUsed.Describe(ch)
	e.isActive.Describe(ch)
	e.ReceivedBytes.Describe(ch)
	e.SentBytes.Describe(ch)
	e.RpcQueueTimeNumOps.Describe(ch)
	e.RpcQueueTimeAvgTime.Describe(ch)
	e.RpcProcessingTimeNumOps.Describe(ch)
	e.RpcProcessingTimeAvgTime.Describe(ch)
	e.RpcAuthenticationFailures.Describe(ch)
	e.RpcAuthenticationSuccesses.Describe(ch)
	e.RpcAuthorizationFailures.Describe(ch)
	e.RpcAuthorizationSuccesses.Describe(ch)
	e.NumOpenConnections.Describe(ch)
	e.CallQueueLength.Describe(ch)
	e.PendingDataNodeMessageCount.Describe(ch)
	e.TransactionsSinceLastCheckpoint.Describe(ch)
	e.LastCheckpointTime.Describe(ch)
	e.MemNonHeapUsedM.Describe(ch)
	e.MemNonHeapCommittedM.Describe(ch)
	e.MemHeapUsedM.Describe(ch)
	e.MemHeapCommittedM.Describe(ch)
	e.MemHeapMaxM.Describe(ch)
	e.MemMaxM.Describe(ch)
	e.GcCount.Describe(ch)
	e.GcTimeMillis.Describe(ch)
	e.ThreadsNew.Describe(ch)
	e.ThreadsRunnable.Describe(ch)
	e.ThreadsBlocked.Describe(ch)
	e.ThreadsWaiting.Describe(ch)
	e.ThreadsTerminated.Describe(ch)
	e.LogFatal.Describe(ch)
	e.LogError.Describe(ch)
	e.LogWarn.Describe(ch)
	e.LogInfo.Describe(ch)
	e.NumStaleStorages.Describe(ch)
	e.NumberOfMissingBlocks.Describe(ch)
	e.Total.Describe(ch)
	e.Used.Describe(ch)
	e.Free.Describe(ch)
	e.PercentUsed.Describe(ch)
	e.BlockPoolUsedSpace.Describe(ch)
	e.PercentBlockPoolUsed.Describe(ch)
	e.PercentRemaining.Describe(ch)
	e.TotalBlocks.Describe(ch)
	e.TotalFiles.Describe(ch)
	e.AllowSnapshotOps.Describe(ch)
	e.DisallowSnapshotOps.Describe(ch)
	e.CreateSnapshotOps.Describe(ch)
	e.DeleteSnapshotOps.Describe(ch)
	e.ListSnapshottableDirOps.Describe(ch)
	e.SnapshotDiffReportOps.Describe(ch)
	e.RenameSnapshotOps.Describe(ch)
	e.CreateFileOps.Describe(ch)
	e.GetListingOps.Describe(ch)
	e.DeleteFileOps.Describe(ch)
	e.FileInfoOps.Describe(ch)
	e.GetAdditionalDatanodeOps.Describe(ch)
	e.CreateSymlinkOps.Describe(ch)
	e.GetLinkTargetOps.Describe(ch)
	e.FilesInGetListingOps.Describe(ch)
	e.FilesDeleted.Describe(ch)
	e.FilesCreated.Describe(ch)
	e.FilesAppended.Describe(ch)
	e.TransactionsNumOps.Describe(ch)
	e.TransactionsBatchedInSync.Describe(ch)
	e.GetEditNumOps.Describe(ch)
	e.GetImageNumOps.Describe(ch)
	e.PutImageNumOps.Describe(ch)
	e.SyncsNumOps.Describe(ch)
	e.BlockReceivedAndDeletedOps.Describe(ch)
	//e.BlockOpsQueued.Describe(ch)
	e.CacheReportNumOps.Describe(ch)
	e.BlockReportNumOps.Describe(ch)
	e.SyncsAvgTime.Describe(ch)
	e.CacheReportAvgTime.Describe(ch)
	e.GetEditAvgTime.Describe(ch)
	e.GetImageAvgTime.Describe(ch)
	e.PutImageAvgTime.Describe(ch)
	e.TransactionsAvgTime.Describe(ch)
	e.PeakThreadCount.Describe(ch)
	e.ThreadCount.Describe(ch)
	e.DaemonThreadCount.Describe(ch)
}

// Collect implements the prometheus.Collector interface.
func (e *Exporter) Collect(ch chan<- prometheus.Metric) {
	resp, err := http.Get(e.url)
	if err != nil {
		log.Error(err)
	}
	defer resp.Body.Close()
	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Error(err)
	}
	var f interface{}
	err = json.Unmarshal(data, &f)
	if err != nil {
		log.Error(err)
	}
	// {"beans":[{"name":"Hadoop:service=NameNode,name=FSNamesystem", ...}, {"name":"java.lang:type=MemoryPool,name=Code Cache", ...}, ...]}
	m := f.(map[string]interface{})
	// [{"name":"Hadoop:service=NameNode,name=FSNamesystem", ...}, {"name":"java.lang:type=MemoryPool,name=Code Cache", ...}, ...]
	var nameList = m["beans"].([]interface{})
	for _, nameData := range nameList {
		nameDataMap := nameData.(map[string]interface{})
		/*
			{
				"name" : "Hadoop:service=NameNode,name=FSNamesystem",
				"modelerType" : "FSNamesystem",
				"tag.Context" : "dfs",
				"tag.HAState" : "active",
				"tag.TotalSyncTimes" : "23 6 ",
				"tag.Hostname" : "CNHORTO7502.line.ism",
				"MissingBlocks" : 0,
				"MissingReplOneBlocks" : 0,
				"ExpiredHeartbeats" : 0,
				"TransactionsSinceLastCheckpoint" : 2007,
				"TransactionsSinceLastLogRoll" : 7,
				"LastWrittenTransactionId" : 172706,
				"LastCheckpointTime" : 1456089173101,
				"CapacityTotal" : 307099828224,
				"CapacityTotalGB" : 286.0,
				"CapacityUsed" : 1471291392,
				"CapacityUsedGB" : 1.0,
				"CapacityRemaining" : 279994568704,
				"CapacityRemainingGB" : 261.0,
				"CapacityUsedNonDFS" : 25633968128,
				"TotalLoad" : 6,
				"SnapshottableDirectories" : 0,
				"Snapshots" : 0,
				"LockQueueLength" : 0,
				"BlocksTotal" : 67,
				"NumFilesUnderConstruction" : 0,
				"NumActiveClients" : 0,
				"FilesTotal" : 184,
				"PendingReplicationBlocks" : 0,
				"UnderReplicatedBlocks" : 0,
				"CorruptBlocks" : 0,
				"ScheduledReplicationBlocks" : 0,
				"PendingDeletionBlocks" : 0,
				"ExcessBlocks" : 0,
				"PostponedMisreplicatedBlocks" : 0,
				"PendingDataNodeMessageCount" : 0,
				"MillisSinceLastLoadedEdits" : 0,
				"BlockCapacity" : 2097152,
				"StaleDataNodes" : 0,
				"TotalFiles" : 184,
				"TotalSyncCount" : 7
			}
		*/
		if nameDataMap["name"] == "Hadoop:service=NameNode,name=FSNamesystem" {
			e.MissingBlocks.Set(nameDataMap["MissingBlocks"].(float64))
			e.CapacityTotal.Set(nameDataMap["CapacityTotal"].(float64))
			e.CapacityUsed.Set(nameDataMap["CapacityUsed"].(float64))
			e.CapacityRemaining.Set(nameDataMap["CapacityRemaining"].(float64))
			e.CapacityUsedNonDFS.Set(nameDataMap["CapacityUsedNonDFS"].(float64))
			e.BlocksTotal.Set(nameDataMap["BlocksTotal"].(float64))
			e.FilesTotal.Set(nameDataMap["FilesTotal"].(float64))
			e.CorruptBlocks.Set(nameDataMap["CorruptBlocks"].(float64))
			e.ExcessBlocks.Set(nameDataMap["ExcessBlocks"].(float64))
			e.StaleDataNodes.Set(nameDataMap["StaleDataNodes"].(float64))
			e.PendingDataNodeMessageCount.Set(nameDataMap["PendingDataNodeMessageCount"].(float64))
			e.TransactionsSinceLastCheckpoint.Set(nameDataMap["TransactionsSinceLastCheckpoint"].(float64))
			e.LastCheckpointTime.Set(nameDataMap["LastCheckpointTime"].(float64))

		}
		if nameDataMap["name"] == "java.lang:type=GarbageCollector,name=ParNew" {
			e.pnGcCount.Set(nameDataMap["CollectionCount"].(float64))
			e.pnGcTime.Set(nameDataMap["CollectionTime"].(float64))
		}
		if nameDataMap["name"] == "java.lang:type=GarbageCollector,name=ConcurrentMarkSweep" {
			e.cmsGcCount.Set(nameDataMap["CollectionCount"].(float64))
			e.cmsGcTime.Set(nameDataMap["CollectionTime"].(float64))
		}
		/*
			"name" : "java.lang:type=Memory",
			"modelerType" : "sun.management.MemoryImpl",
			"HeapMemoryUsage" : {
				"committed" : 1060372480,
				"init" : 1073741824,
				"max" : 1060372480,
				"used" : 124571464
			},
		*/
		if nameDataMap["name"] == "java.lang:type=Memory" {
			heapMemoryUsage := nameDataMap["HeapMemoryUsage"].(map[string]interface{})
			e.heapMemoryUsageCommitted.Set(heapMemoryUsage["committed"].(float64))
			e.heapMemoryUsageInit.Set(heapMemoryUsage["init"].(float64))
			e.heapMemoryUsageMax.Set(heapMemoryUsage["max"].(float64))
			e.heapMemoryUsageUsed.Set(heapMemoryUsage["used"].(float64))
		}

		if nameDataMap["name"] == "Hadoop:service=NameNode,name=FSNamesystem" {
			if nameDataMap["tag.HAState"] == "active" {
				e.isActive.Set(1)
			} else {
				e.isActive.Set(0)
			}
		}

		if nameDataMap["name"] == "Hadoop:service=NameNode,name=RpcActivityForPort8020" {
			e.ReceivedBytes.Set(nameDataMap["ReceivedBytes"].(float64))
			e.SentBytes.Set(nameDataMap["SentBytes"].(float64))
			e.RpcQueueTimeNumOps.Set(nameDataMap["RpcQueueTimeNumOps"].(float64))
			e.RpcQueueTimeAvgTime.Set(nameDataMap["RpcQueueTimeAvgTime"].(float64))
			e.RpcProcessingTimeNumOps.Set(nameDataMap["RpcProcessingTimeNumOps"].(float64))
			e.RpcProcessingTimeAvgTime.Set(nameDataMap["RpcProcessingTimeAvgTime"].(float64))
			e.RpcAuthenticationFailures.Set(nameDataMap["RpcAuthenticationFailures"].(float64))
			e.RpcAuthenticationSuccesses.Set(nameDataMap["RpcAuthenticationSuccesses"].(float64))
			e.RpcAuthorizationFailures.Set(nameDataMap["RpcAuthorizationFailures"].(float64))
			e.RpcAuthorizationSuccesses.Set(nameDataMap["RpcAuthorizationSuccesses"].(float64))
			e.NumOpenConnections.Set(nameDataMap["NumOpenConnections"].(float64))
			e.CallQueueLength.Set(nameDataMap["CallQueueLength"].(float64))
		}

		//JVM 内存
		if nameDataMap["name"] == "Hadoop:service=NameNode,name=JvmMetrics" {
			e.MemNonHeapUsedM.Set(nameDataMap["MemNonHeapUsedM"].(float64))
			e.MemNonHeapCommittedM.Set(nameDataMap["MemNonHeapCommittedM"].(float64))
			e.MemHeapUsedM.Set(nameDataMap["MemHeapUsedM"].(float64))
			e.MemHeapCommittedM.Set(nameDataMap["MemHeapCommittedM"].(float64))
			e.MemHeapMaxM.Set(nameDataMap["MemHeapMaxM"].(float64))
			e.MemMaxM.Set(nameDataMap["MemMaxM"].(float64))
			e.GcCount.Set(nameDataMap["GcCount"].(float64))
			e.GcTimeMillis.Set(nameDataMap["GcTimeMillis"].(float64))
			e.ThreadsNew.Set(nameDataMap["ThreadsNew"].(float64))
			e.ThreadsRunnable.Set(nameDataMap["ThreadsRunnable"].(float64))
			e.ThreadsBlocked.Set(nameDataMap["ThreadsBlocked"].(float64))
			e.ThreadsWaiting.Set(nameDataMap["ThreadsWaiting"].(float64))
			e.ThreadsTerminated.Set(nameDataMap["ThreadsTerminated"].(float64))
			e.LogFatal.Set(nameDataMap["LogFatal"].(float64))
			e.LogError.Set(nameDataMap["LogError"].(float64))
			e.LogWarn.Set(nameDataMap["LogWarn"].(float64))
			e.LogInfo.Set(nameDataMap["LogInfo"].(float64))
		}

		//FSNamesystemState
		if nameDataMap["name"] == "Hadoop:service=NameNode,name=FSNamesystemState" {
			e.NumStaleStorages.Set(nameDataMap["NumStaleStorages"].(float64))
		}

		//NameNodeInfo
		if nameDataMap["name"] == "Hadoop:service=NameNode,name=NameNodeInfo" {
			e.NumberOfMissingBlocks.Set(nameDataMap["NumberOfMissingBlocks"].(float64))
			e.Total.Set(nameDataMap["Total"].(float64))
			e.Used.Set(nameDataMap["Used"].(float64))
			e.Free.Set(nameDataMap["Free"].(float64))
			e.PercentUsed.Set(nameDataMap["PercentUsed"].(float64))
			e.BlockPoolUsedSpace.Set(nameDataMap["BlockPoolUsedSpace"].(float64))
			e.PercentBlockPoolUsed.Set(nameDataMap["PercentBlockPoolUsed"].(float64))
			e.PercentRemaining.Set(nameDataMap["PercentRemaining"].(float64))
			e.TotalBlocks.Set(nameDataMap["TotalBlocks"].(float64))
			e.TotalFiles.Set(nameDataMap["TotalFiles"].(float64))
		}


		//NameNodeActivity
		if nameDataMap["name"] == "Hadoop:service=NameNode,name=NameNodeActivity" {
			e.AllowSnapshotOps.Set(nameDataMap["AllowSnapshotOps"].(float64))
			e.DisallowSnapshotOps.Set(nameDataMap["DisallowSnapshotOps"].(float64))
			e.CreateSnapshotOps.Set(nameDataMap["CreateSnapshotOps"].(float64))
			e.DeleteSnapshotOps.Set(nameDataMap["DeleteSnapshotOps"].(float64))
			e.ListSnapshottableDirOps.Set(nameDataMap["ListSnapshottableDirOps"].(float64))
			e.SnapshotDiffReportOps.Set(nameDataMap["SnapshotDiffReportOps"].(float64))
			e.RenameSnapshotOps.Set(nameDataMap["RenameSnapshotOps"].(float64))
			//文件操作
			e.CreateFileOps.Set(nameDataMap["CreateFileOps"].(float64))
			e.GetListingOps.Set(nameDataMap["GetListingOps"].(float64))
			//e.TotalFileOps.Set(nameDataMap["TotalFileOps"].(float64))
			e.DeleteFileOps.Set(nameDataMap["DeleteFileOps"].(float64))
			e.FileInfoOps.Set(nameDataMap["FileInfoOps"].(float64))
			e.GetAdditionalDatanodeOps.Set(nameDataMap["GetAdditionalDatanodeOps"].(float64))
			e.CreateSymlinkOps.Set(nameDataMap["CreateSymlinkOps"].(float64))
			e.GetLinkTargetOps.Set(nameDataMap["GetLinkTargetOps"].(float64))
			e.FilesInGetListingOps.Set(nameDataMap["FilesInGetListingOps"].(float64))
			//文件统计
			e.FilesDeleted.Set(nameDataMap["FilesDeleted"].(float64))
			e.FilesCreated.Set(nameDataMap["FilesCreated"].(float64))
			e.FilesAppended.Set(nameDataMap["FilesAppended"].(float64))
			//事务操作
			e.TransactionsNumOps.Set(nameDataMap["TransactionsNumOps"].(float64))
			e.TransactionsBatchedInSync.Set(nameDataMap["TransactionsBatchedInSync"].(float64))
			//镜像操作
			e.GetEditNumOps.Set(nameDataMap["GetEditNumOps"].(float64))
			e.GetImageNumOps.Set(nameDataMap["GetImageNumOps"].(float64))
			e.PutImageNumOps.Set(nameDataMap["PutImageNumOps"].(float64))
			//SYNC 操作
			e.SyncsNumOps.Set(nameDataMap["SyncsNumOps"].(float64))
			//数据块操作
			e.BlockReceivedAndDeletedOps.Set(nameDataMap["BlockReceivedAndDeletedOps"].(float64))
			//e.BlockOpsQueued.Set(nameDataMap["BlockOpsQueued"].(float64))
			//缓存汇报
			e.CacheReportNumOps.Set(nameDataMap["CacheReportNumOps"].(float64))
			//数据块汇报
			e.BlockReportNumOps.Set(nameDataMap["BlockReportNumOps"].(float64))
			e.SyncsAvgTime.Set(nameDataMap["SyncsAvgTime"].(float64))
			e.CacheReportAvgTime.Set(nameDataMap["CacheReportAvgTime"].(float64))
			//镜像操作延迟
			e.GetEditAvgTime.Set(nameDataMap["GetEditAvgTime"].(float64))
			e.GetImageAvgTime.Set(nameDataMap["GetImageAvgTime"].(float64))
			e.PutImageAvgTime.Set(nameDataMap["PutImageAvgTime"].(float64))
			//事务操作延迟
			e.TransactionsAvgTime.Set(nameDataMap["TransactionsAvgTime"].(float64))

		}

		//线程数量
		if nameDataMap["name"] == "java.lang:type=Threading" {
			e.PeakThreadCount.Set(nameDataMap["PeakThreadCount"].(float64))
			e.ThreadCount.Set(nameDataMap["ThreadCount"].(float64))
			e.DaemonThreadCount.Set(nameDataMap["DaemonThreadCount"].(float64))
		}



	}
	e.MissingBlocks.Collect(ch)
	e.CapacityTotal.Collect(ch)
	e.CapacityUsed.Collect(ch)
	e.CapacityRemaining.Collect(ch)
	e.CapacityUsedNonDFS.Collect(ch)
	e.BlocksTotal.Collect(ch)
	e.FilesTotal.Collect(ch)
	e.CorruptBlocks.Collect(ch)
	e.ExcessBlocks.Collect(ch)
	e.StaleDataNodes.Collect(ch)
	e.pnGcCount.Collect(ch)
	e.pnGcTime.Collect(ch)
	e.cmsGcCount.Collect(ch)
	e.cmsGcTime.Collect(ch)
	e.heapMemoryUsageCommitted.Collect(ch)
	e.heapMemoryUsageInit.Collect(ch)
	e.heapMemoryUsageMax.Collect(ch)
	e.heapMemoryUsageUsed.Collect(ch)
	e.isActive.Collect(ch)
	e.ReceivedBytes.Collect(ch)
	e.SentBytes.Collect(ch)
	e.RpcQueueTimeNumOps.Collect(ch)
	e.RpcQueueTimeAvgTime.Collect(ch)
	e.RpcProcessingTimeNumOps.Collect(ch)
	e.RpcProcessingTimeAvgTime.Collect(ch)
	e.RpcAuthenticationFailures.Collect(ch)
	e.RpcAuthenticationSuccesses.Collect(ch)
	e.RpcAuthorizationFailures.Collect(ch)
	e.RpcAuthorizationSuccesses.Collect(ch)
	e.NumOpenConnections.Collect(ch)
	e.CallQueueLength.Collect(ch)
	e.PendingDataNodeMessageCount.Collect(ch)
	e.TransactionsSinceLastCheckpoint.Collect(ch)
	e.LastCheckpointTime.Collect(ch)
	e.MemNonHeapUsedM.Collect(ch)
	e.MemNonHeapCommittedM.Collect(ch)
	e.MemHeapUsedM.Collect(ch)
	e.MemHeapCommittedM.Collect(ch)
	e.MemHeapMaxM.Collect(ch)
	e.MemMaxM.Collect(ch)
	e.GcCount.Collect(ch)
	e.GcTimeMillis.Collect(ch)
	e.ThreadsNew.Collect(ch)
	e.ThreadsRunnable.Collect(ch)
	e.ThreadsBlocked.Collect(ch)
	e.ThreadsWaiting.Collect(ch)
	e.ThreadsTerminated.Collect(ch)
	e.LogFatal.Collect(ch)
	e.LogError.Collect(ch)
	e.LogWarn.Collect(ch)
	e.LogInfo.Collect(ch)
	e.NumStaleStorages.Collect(ch)
	e.NumberOfMissingBlocks.Collect(ch)
	e.Total.Collect(ch)
	e.Used.Collect(ch)
	e.Free.Collect(ch)
	e.PercentUsed.Collect(ch)
	e.BlockPoolUsedSpace.Collect(ch)
	e.PercentBlockPoolUsed.Collect(ch)
	e.PercentRemaining.Collect(ch)
	e.TotalBlocks.Collect(ch)
	e.TotalFiles.Collect(ch)
	e.AllowSnapshotOps.Collect(ch)
	e.DisallowSnapshotOps.Collect(ch)
	e.CreateSnapshotOps.Collect(ch)
	e.DeleteSnapshotOps.Collect(ch)
	e.ListSnapshottableDirOps.Collect(ch)
	e.SnapshotDiffReportOps.Collect(ch)
	e.RenameSnapshotOps.Collect(ch)
	e.CreateFileOps.Collect(ch)
	e.GetListingOps.Collect(ch)
	e.DeleteFileOps.Collect(ch)
	e.FileInfoOps.Collect(ch)
	e.GetAdditionalDatanodeOps.Collect(ch)
	e.CreateSymlinkOps.Collect(ch)
	e.GetLinkTargetOps.Collect(ch)
	e.FilesInGetListingOps.Collect(ch)
	e.FilesDeleted.Collect(ch)
	e.FilesCreated.Collect(ch)
	e.FilesAppended.Collect(ch)
	e.TransactionsNumOps.Collect(ch)
	e.TransactionsBatchedInSync.Collect(ch)
	e.GetEditNumOps.Collect(ch)
	e.GetImageNumOps.Collect(ch)
	e.PutImageNumOps.Collect(ch)
	e.SyncsNumOps.Collect(ch)
	e.BlockReceivedAndDeletedOps.Collect(ch)
	//e.BlockOpsQueued.Collect(ch)
	e.CacheReportNumOps.Collect(ch)
	e.BlockReportNumOps.Collect(ch)
	e.SyncsAvgTime.Collect(ch)
	e.CacheReportAvgTime.Collect(ch)
	e.GetEditAvgTime.Collect(ch)
	e.GetImageAvgTime.Collect(ch)
	e.PutImageAvgTime.Collect(ch)
	e.TransactionsAvgTime.Collect(ch)
	e.PeakThreadCount.Collect(ch)
	e.ThreadCount.Collect(ch)
	e.DaemonThreadCount.Collect(ch)

}

func main() {
	flag.Parse()

	exporter := NewExporter(*namenodeJmxUrl)
	prometheus.MustRegister(exporter)

	log.Printf("Starting Server: %s", *listenAddress)
	http.Handle(*metricsPath, prometheus.Handler())
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte(`<html>
		<head><title>NameNode Exporter</title></head>
		<body>
		<h1>NameNode Exporter</h1>
		<p><a href="` + *metricsPath + `">Metrics</a></p>
		</body>
		</html>`))
	})
	err := http.ListenAndServe(*listenAddress, nil)
	log.Printf("namenode jmxurl: %s",*metricsPath)
	if err != nil {
		log.Fatal(err)
	}

}
